{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Notes:\n",
    " * revised and tuned configuration, updated views\n",
    " * training on full dataset (including Y3, new light curves, fixes)\n",
    " * trained with updated star radius estimations, multiple duplicates removed\n",
    " * removed instar examples"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['/mnt/tess/astronet/checkpoints/ext_35_run_1/1/AstroCNNModel_extended_20220328_165807',\n",
       " '/mnt/tess/astronet/checkpoints/ext_35_run_1/2/AstroCNNModel_extended_20220328_173327',\n",
       " '/mnt/tess/astronet/checkpoints/ext_35_run_1/3/AstroCNNModel_extended_20220328_180751',\n",
       " '/mnt/tess/astronet/checkpoints/ext_35_run_1/4/AstroCNNModel_extended_20220328_184213',\n",
       " '/mnt/tess/astronet/checkpoints/ext_35_run_1/5/AstroCNNModel_extended_20220328_191617',\n",
       " '/mnt/tess/astronet/checkpoints/ext_35_run_1/6/AstroCNNModel_extended_20220328_194914',\n",
       " '/mnt/tess/astronet/checkpoints/ext_35_run_1/7/AstroCNNModel_extended_20220328_202225',\n",
       " '/mnt/tess/astronet/checkpoints/ext_35_run_1/8/AstroCNNModel_extended_20220328_205525',\n",
       " '/mnt/tess/astronet/checkpoints/ext_35_run_1/9/AstroCNNModel_extended_20220328_212823',\n",
       " '/mnt/tess/astronet/checkpoints/ext_35_run_1/10/AstroCNNModel_extended_20220328_220115']"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import os\n",
    "\n",
    "chkpt_root = '/mnt/tess/astronet/checkpoints/ext_35_run_1'\n",
    "data_files = '/mnt/tess/astronet/tfrecords-35-train/*'\n",
    "tces_file = '/mnt/tess/astronet/tces-v12-train.csv'\n",
    "\n",
    "nruns = 10\n",
    "\n",
    "def load_ensemble(chkpt_root, nruns):\n",
    "    checkpts = []\n",
    "    for i in range(nruns):\n",
    "        parent = os.path.join(chkpt_root, str(i + 1))\n",
    "        if not os.path.exists(parent):\n",
    "            break\n",
    "        all_dirs = os.listdir(parent)\n",
    "        if not all_dirs:\n",
    "            break\n",
    "        d, = all_dirs\n",
    "        checkpts.append(os.path.join(parent, d))\n",
    "    return checkpts\n",
    "\n",
    "paths = load_ensemble(chkpt_root, nruns)\n",
    "paths"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Running model 1\n",
      "19698 records\n",
      "Running model 2\n",
      "19698 records\n",
      "Running model 3\n",
      "19698 records\n",
      "Running model 4\n",
      "19698 records\n",
      "Running model 5\n",
      "19698 records\n",
      "Running model 6\n",
      "19698 records\n",
      "Running model 7\n",
      "19698 records\n",
      "Running model 8\n",
      "19698 records\n",
      "Running model 9\n",
      "19698 records\n",
      "Running model 10\n",
      "19698 records\n"
     ]
    }
   ],
   "source": [
    "import getpass\n",
    "import os\n",
    "from astronet import predict\n",
    "import tensorflow as tf\n",
    "\n",
    "\n",
    "def run_predictions(path):\n",
    "    predict.FLAGS = predict.parser.parse_args([\n",
    "      '--model_dir', path,\n",
    "      '--data_files', data_files,\n",
    "      '--output_file', '',\n",
    "    ])\n",
    "\n",
    "    return predict.predict()\n",
    "\n",
    "\n",
    "paths = load_ensemble(chkpt_root, nruns)\n",
    "ensemble_preds = []\n",
    "config = None\n",
    "for i, path in enumerate(paths):\n",
    "    print(f'Running model {i + 1}')\n",
    "    preds, config = run_predictions(path)\n",
    "    ensemble_preds.append(preds.set_index('tic_id'))\n",
    "    print()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "labels = ['disp_e', 'disp_n', 'disp_j', 'disp_s', 'disp_b']\n",
    "\n",
    "col_e = labels.index('disp_e')\n",
    "thresh = 0.2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "\n",
    "agg_preds = {}\n",
    "\n",
    "for preds in ensemble_preds:\n",
    "    for tic_id in preds.index:\n",
    "        if tic_id not in agg_preds:\n",
    "            agg_preds[tic_id] = []\n",
    "\n",
    "        row = preds[preds.index == tic_id]\n",
    "        pred_v = row.values[0]\n",
    "        if len(row.values) > 1:\n",
    "            print(f'Warning: duplicate predictions for {tic_id}')\n",
    "        if pred_v[col_e] >= thresh:\n",
    "            agg_preds[tic_id].append('disp_e')\n",
    "        else:\n",
    "            masked_v = [v if i != col_e else 0 for i, v in enumerate(pred_v)]\n",
    "            agg_preds[tic_id].append(preds.columns[np.argmax(masked_v)])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "final_preds = []\n",
    "for tic_id in list(agg_preds.keys()):\n",
    "    counts = {l: 0 for l in labels}\n",
    "    for e in agg_preds[tic_id]:\n",
    "        counts[e] += 1\n",
    "    maxcount = max(counts.values())\n",
    "    counts.update({\n",
    "        'tic_id': tic_id,\n",
    "        'maxcount': maxcount,\n",
    "    })\n",
    "    final_preds.append(counts)\n",
    "    \n",
    "final_preds = pd.DataFrame(final_preds).set_index('tic_id')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "tce_table = pd.read_csv(tces_file, header=0).set_index('tic_id')\n",
    "for l in labels:\n",
    "    tce_table[l] = tce_table[l[:-1] + l[-1].upper()]\n",
    "tce_labels = tce_table[labels]\n",
    "\n",
    "pl = final_preds.join(tce_labels, on='tic_id', how='left', lsuffix='_p')\n",
    "\n",
    "pl.head()\n",
    "pd.set_option('display.max_columns', None)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Recall: 0.9956772334293948\n",
      "Precision: 0.7960829493087558\n"
     ]
    }
   ],
   "source": [
    "ppos = (pl['disp_e_p'] > 0)\n",
    "pos = (pl['disp_e'] > 0)\n",
    "\n",
    "pneg = (pl['disp_e_p'] == 0)\n",
    "neg = (pl['disp_e'] == 0)\n",
    "\n",
    "print('Recall:', len(pl[ppos & pos]) / len(pl[pos]))\n",
    "print('Precision:', len(pl[ppos & pos]) / len(pl[ppos]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "387829772\n",
      "369860950\n",
      "379464439\n",
      "381366555\n",
      "761960972\n",
      "49799681\n",
      "294092966\n",
      "176582931\n",
      "152539284\n"
     ]
    }
   ],
   "source": [
    "for i in pl[pos & pneg][[]].join(tce_table, on='tic_id', how='left').index:\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "384490098\n",
      "384608233\n",
      "387060242\n",
      "389363745\n",
      "389576843\n",
      "389668544\n",
      "390561536\n",
      "391745260\n",
      "391811200\n",
      "391821647\n",
      "392793407\n",
      "394233079\n",
      "394284999\n",
      "394345045\n",
      "394358240\n",
      "394372611\n",
      "396957480\n",
      "298896016\n",
      "252809234\n",
      "29020857\n",
      "292464126\n",
      "322060802\n",
      "326919774\n",
      "332051907\n",
      "333064504\n",
      "348518919\n",
      "9061195\n",
      "165689608\n",
      "193948281\n",
      "199572752\n",
      "235562906\n",
      "236896126\n",
      "236897301\n",
      "259879138\n",
      "343463316\n",
      "417057112\n",
      "418749263\n",
      "430689771\n",
      "455588711\n",
      "455698002\n",
      "468488829\n",
      "173710176\n",
      "18252911\n",
      "186302615\n",
      "252546286\n",
      "252733538\n",
      "252778660\n",
      "25823018\n",
      "25918053\n",
      "26821153\n",
      "336799587\n",
      "148963635\n",
      "154006988\n",
      "156458268\n",
      "156993882\n",
      "165428216\n",
      "18919598\n",
      "198536950\n",
      "388906923\n",
      "101654574\n",
      "101821550\n",
      "112716272\n",
      "112830723\n",
      "119088593\n",
      "119384992\n",
      "119433341\n",
      "120401906\n",
      "128800217\n",
      "128846212\n",
      "128882149\n",
      "140688564\n",
      "140691839\n",
      "141096229\n",
      "141545493\n",
      "141610473\n",
      "423238309\n",
      "425083216\n",
      "425083264\n",
      "431380283\n",
      "441221559\n",
      "446348045\n",
      "451540413\n",
      "451568159\n",
      "453100472\n",
      "456516439\n",
      "456588598\n",
      "456611584\n",
      "464488581\n",
      "466098380\n",
      "467902598\n",
      "468216079\n",
      "469269031\n",
      "49449799\n",
      "50308490\n",
      "369834384\n",
      "369864019\n",
      "369932580\n",
      "370101492\n",
      "370134610\n",
      "370227480\n",
      "373522149\n",
      "373523051\n",
      "373840212\n",
      "373843852\n",
      "373843857\n",
      "373919389\n",
      "375090717\n",
      "379192021\n",
      "379239816\n",
      "381798773\n",
      "382625239\n",
      "382626168\n",
      "383630403\n",
      "384077498\n",
      "384195094\n",
      "384196457\n",
      "43667308\n",
      "452741460\n",
      "63555629\n",
      "63931474\n",
      "92774987\n",
      "98937256\n",
      "99396894\n",
      "120598737\n",
      "120602501\n",
      "128379228\n",
      "139258713\n",
      "154096314\n",
      "174042805\n",
      "2008877991\n",
      "236647148\n",
      "257582255\n",
      "258351350\n",
      "271809828\n",
      "272358852\n",
      "272362769\n",
      "273790497\n",
      "274017873\n",
      "276793626\n",
      "277022748\n",
      "277022838\n",
      "277026183\n",
      "277027632\n",
      "277101021\n",
      "277297046\n",
      "277298580\n",
      "277299710\n",
      "278539271\n",
      "40993256\n",
      "420177694\n",
      "42321328\n",
      "70013723\n",
      "83408987\n",
      "99222716\n",
      "100165164\n",
      "117631084\n",
      "12675678\n",
      "159173586\n",
      "161563111\n",
      "169934335\n",
      "170932338\n",
      "17131560\n",
      "171777882\n",
      "185011414\n",
      "185779149\n",
      "349573707\n",
      "349635294\n",
      "360961597\n",
      "362081519\n",
      "363485837\n",
      "363979429\n",
      "364873540\n",
      "229669567\n",
      "23769815\n",
      "27349529\n",
      "27434899\n",
      "27462264\n",
      "286945730\n",
      "287135515\n",
      "298263938\n",
      "310003047\n",
      "365089053\n",
      "368077227\n",
      "405526038\n",
      "61110114\n",
      "1884267302\n",
      "300241544\n",
      "30031180\n",
      "300557619\n",
      "300734224\n",
      "30110707\n",
      "30113151\n",
      "301896004\n",
      "30193373\n",
      "301955257\n",
      "30267088\n",
      "302965287\n",
      "302966331\n",
      "30313096\n",
      "304135720\n",
      "304864057\n",
      "306108833\n",
      "306196907\n",
      "306270678\n",
      "306352399\n",
      "30641264\n",
      "306890368\n",
      "307035723\n",
      "30844506\n",
      "30906987\n",
      "309654719\n",
      "309760042\n",
      "310360141\n",
      "311035084\n",
      "311415911\n",
      "31167034\n",
      "312028996\n",
      "31391041\n",
      "31415158\n",
      "31634175\n",
      "317022274\n",
      "31942558\n",
      "467354611\n",
      "9779230\n",
      "36279\n",
      "712837\n",
      "4933576\n",
      "10935045\n",
      "358249491\n",
      "363655532\n",
      "366406728\n",
      "389078181\n",
      "390959699\n",
      "391044439\n",
      "406403918\n",
      "438065345\n",
      "440738016\n",
      "442692020\n",
      "453009027\n",
      "454140642\n",
      "454148037\n",
      "457681334\n",
      "458108252\n",
      "463974233\n",
      "340217291\n",
      "341077740\n",
      "341082784\n",
      "343578197\n",
      "348899878\n",
      "349060295\n",
      "349061746\n",
      "349154278\n",
      "349373192\n",
      "349485058\n",
      "278988513\n",
      "278990954\n",
      "279161495\n",
      "279250153\n",
      "279614421\n",
      "279615956\n",
      "27968643\n",
      "279956763\n",
      "279957439\n",
      "279958091\n",
      "280097876\n",
      "280098252\n",
      "284196025\n",
      "284196801\n",
      "287769668\n",
      "287775969\n",
      "61136885\n",
      "61614242\n",
      "62023270\n",
      "74649892\n",
      "75683740\n",
      "75687121\n",
      "79655149\n",
      "86144938\n",
      "87164255\n",
      "87168122\n",
      "87339522\n",
      "87708224\n",
      "88353444\n",
      "89307726\n",
      "89740313\n",
      "90161731\n",
      "90562888\n",
      "90563464\n",
      "90716944\n",
      "91073914\n",
      "455817128\n",
      "137906810\n",
      "230966538\n",
      "230968587\n",
      "231792014\n",
      "23497144\n",
      "238180562\n",
      "238189546\n",
      "238229126\n",
      "238869865\n",
      "238893940\n",
      "246288840\n",
      "246290171\n",
      "25078924\n",
      "254158487\n",
      "255991074\n",
      "257738254\n",
      "257772292\n",
      "257772293\n",
      "260266599\n",
      "260302494\n",
      "260304296\n",
      "260414617\n",
      "260605127\n",
      "268308889\n",
      "273226805\n",
      "277316602\n",
      "281597511\n",
      "281667628\n",
      "300029336\n",
      "303557843\n",
      "305582965\n",
      "307999339\n",
      "309472493\n",
      "316880689\n",
      "354624921\n",
      "374298760\n",
      "405460905\n",
      "428203967\n",
      "445417446\n",
      "55000411\n",
      "641539146\n",
      "32000208\n",
      "32000625\n",
      "323135338\n",
      "325603650\n",
      "326606721\n",
      "326693703\n",
      "326903459\n",
      "327595687\n",
      "327681256\n",
      "33862068\n",
      "339633666\n",
      "339735718\n",
      "13137970\n",
      "13346068\n",
      "20925093\n",
      "23215769\n",
      "32449778\n",
      "47316976\n",
      "47390165\n",
      "50269985\n",
      "62971651\n",
      "67688551\n",
      "76504356\n",
      "76698707\n",
      "106108969\n",
      "121741238\n",
      "122220263\n",
      "122673496\n",
      "137147023\n",
      "244857422\n",
      "359729929\n",
      "390349501\n",
      "404355884\n",
      "219485088\n",
      "258514380\n",
      "321446538\n",
      "167724589\n",
      "167890671\n",
      "177389419\n",
      "179305059\n",
      "179308949\n",
      "180416902\n",
      "181656057\n",
      "182450724\n",
      "182650117\n",
      "198051336\n",
      "201563776\n",
      "201601348\n",
      "21995336\n",
      "220371571\n",
      "220375993\n",
      "219807730\n",
      "229434615\n",
      "290605311\n",
      "293438120\n",
      "293464697\n",
      "293571051\n",
      "293571145\n",
      "294871044\n",
      "295372927\n",
      "29924770\n",
      "29984021\n",
      "29990829\n",
      "299936689\n",
      "377197068\n",
      "261136311\n",
      "261422404\n",
      "266926793\n",
      "266970704\n",
      "267434733\n",
      "268813100\n",
      "270312314\n",
      "270365850\n",
      "271577058\n",
      "142013907\n",
      "142109185\n",
      "150394361\n",
      "166280254\n",
      "202563294\n",
      "233896030\n",
      "239294743\n",
      "260700439\n",
      "268608949\n",
      "275761018\n",
      "282173645\n",
      "298295539\n",
      "299156852\n",
      "329704753\n",
      "378275445\n",
      "380289423\n",
      "380717831\n",
      "380794470\n",
      "436005037\n",
      "94368545\n",
      "122280962\n",
      "122626372\n",
      "148392230\n",
      "239814191\n",
      "252365657\n",
      "260234392\n",
      "260593481\n",
      "260593507\n",
      "260686230\n",
      "262169297\n",
      "266428346\n",
      "267694283\n",
      "273091578\n",
      "2772728\n",
      "309682332\n",
      "322399290\n",
      "3311888\n",
      "346987279\n",
      "348468490\n",
      "26547036\n",
      "266908723\n",
      "276553165\n",
      "277566483\n",
      "290310072\n",
      "305479069\n",
      "343465205\n",
      "374137958\n",
      "40342199\n",
      "404035038\n",
      "404224560\n",
      "404603404\n",
      "404768904\n",
      "404799340\n",
      "404842248\n",
      "404851226\n",
      "404851347\n",
      "404851658\n",
      "404931649\n",
      "404933877\n",
      "40515061\n",
      "405864709\n",
      "406240476\n",
      "407063129\n",
      "409639832\n",
      "40974499\n",
      "409885356\n",
      "410228822\n",
      "41111279\n",
      "411829582\n",
      "411917726\n",
      "417920762\n",
      "459218950\n",
      "82308728\n",
      "150436377\n",
      "180627814\n",
      "356630364\n",
      "356744650\n",
      "99784331\n",
      "10219190\n",
      "141816125\n",
      "354785553\n",
      "354959477\n",
      "356494155\n",
      "392426715\n",
      "400893171\n",
      "414897731\n",
      "424277160\n",
      "445706410\n",
      "446012335\n",
      "470358759\n",
      "60385535\n",
      "664035272\n",
      "701040921\n",
      "82166856\n",
      "82620914\n",
      "88129419\n",
      "174203886\n",
      "209407002\n",
      "219332212\n",
      "220474216\n",
      "220524382\n",
      "234331809\n",
      "237944314\n",
      "248988133\n",
      "82806895\n",
      "90128622\n",
      "96315559\n",
      "98548087\n",
      "105450460\n",
      "118717588\n",
      "131857479\n",
      "141028198\n",
      "150104471\n",
      "152222884\n",
      "153408739\n",
      "159638137\n",
      "165492094\n",
      "9483535\n",
      "103691355\n",
      "105378745\n",
      "117247505\n",
      "117247507\n",
      "138576706\n",
      "142487281\n",
      "142792148\n"
     ]
    }
   ],
   "source": [
    "for i in pl[neg & ppos][[]].join(tce_table, on='tic_id', how='left').index:\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>disp_e</th>\n",
       "      <th>disp_n</th>\n",
       "      <th>disp_j</th>\n",
       "      <th>disp_s</th>\n",
       "      <th>disp_b</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>tic_id</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>150104471</th>\n",
       "      <td>0.061691</td>\n",
       "      <td>0.273432</td>\n",
       "      <td>0.896241</td>\n",
       "      <td>0.004004</td>\n",
       "      <td>0.042941</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>150104471</th>\n",
       "      <td>0.024685</td>\n",
       "      <td>0.264496</td>\n",
       "      <td>0.931150</td>\n",
       "      <td>0.021045</td>\n",
       "      <td>0.039660</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>150104471</th>\n",
       "      <td>0.181032</td>\n",
       "      <td>0.354968</td>\n",
       "      <td>0.675627</td>\n",
       "      <td>0.009032</td>\n",
       "      <td>0.028122</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>150104471</th>\n",
       "      <td>0.431361</td>\n",
       "      <td>0.279017</td>\n",
       "      <td>0.447954</td>\n",
       "      <td>0.013327</td>\n",
       "      <td>0.013390</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>150104471</th>\n",
       "      <td>0.098898</td>\n",
       "      <td>0.383983</td>\n",
       "      <td>0.819418</td>\n",
       "      <td>0.005780</td>\n",
       "      <td>0.041152</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>150104471</th>\n",
       "      <td>0.094811</td>\n",
       "      <td>0.305148</td>\n",
       "      <td>0.791707</td>\n",
       "      <td>0.024258</td>\n",
       "      <td>0.139891</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>150104471</th>\n",
       "      <td>0.081163</td>\n",
       "      <td>0.414341</td>\n",
       "      <td>0.799552</td>\n",
       "      <td>0.012373</td>\n",
       "      <td>0.036905</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>150104471</th>\n",
       "      <td>0.098791</td>\n",
       "      <td>0.272337</td>\n",
       "      <td>0.807104</td>\n",
       "      <td>0.014567</td>\n",
       "      <td>0.020798</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>150104471</th>\n",
       "      <td>0.114436</td>\n",
       "      <td>0.395542</td>\n",
       "      <td>0.731846</td>\n",
       "      <td>0.026271</td>\n",
       "      <td>0.020404</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>150104471</th>\n",
       "      <td>0.213778</td>\n",
       "      <td>0.258786</td>\n",
       "      <td>0.617948</td>\n",
       "      <td>0.015894</td>\n",
       "      <td>0.024817</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             disp_e    disp_n    disp_j    disp_s    disp_b\n",
       "tic_id                                                     \n",
       "150104471  0.061691  0.273432  0.896241  0.004004  0.042941\n",
       "150104471  0.024685  0.264496  0.931150  0.021045  0.039660\n",
       "150104471  0.181032  0.354968  0.675627  0.009032  0.028122\n",
       "150104471  0.431361  0.279017  0.447954  0.013327  0.013390\n",
       "150104471  0.098898  0.383983  0.819418  0.005780  0.041152\n",
       "150104471  0.094811  0.305148  0.791707  0.024258  0.139891\n",
       "150104471  0.081163  0.414341  0.799552  0.012373  0.036905\n",
       "150104471  0.098791  0.272337  0.807104  0.014567  0.020798\n",
       "150104471  0.114436  0.395542  0.731846  0.026271  0.020404\n",
       "150104471  0.213778  0.258786  0.617948  0.015894  0.024817"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def compare(ensemble_preds, filter):\n",
    "    result = ensemble_preds[0][filter]\n",
    "    for preds in ensemble_preds[1:]:\n",
    "        result = result.append(preds[filter])\n",
    "    return result\n",
    "\n",
    "compare(ensemble_preds, preds.index == 150104471)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>disp_e_p</th>\n",
       "      <th>disp_n_p</th>\n",
       "      <th>disp_j_p</th>\n",
       "      <th>disp_s_p</th>\n",
       "      <th>disp_b_p</th>\n",
       "      <th>maxcount</th>\n",
       "      <th>disp_e</th>\n",
       "      <th>disp_n</th>\n",
       "      <th>disp_j</th>\n",
       "      <th>disp_s</th>\n",
       "      <th>disp_b</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>tic_id</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "Empty DataFrame\n",
       "Columns: [disp_e_p, disp_n_p, disp_j_p, disp_s_p, disp_b_p, maxcount, disp_e, disp_n, disp_j, disp_s, disp_b]\n",
       "Index: []"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pl[pl.index == 340066802]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### PR curve"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "tics = set(ensemble_preds[0].index.values)\n",
    "\n",
    "tic_index = {v: i for i, v in enumerate(tics)}\n",
    "\n",
    "pred_es = np.zeros([len(ensemble_preds), len(tic_index)])\n",
    "for i, preds in enumerate(ensemble_preds):\n",
    "    for row in preds.iterrows():\n",
    "        tic, pred_e = row[0], row[1][col_e]\n",
    "        pred_es[i][tic_index[tic]] = pred_e\n",
    "\n",
    "lbl_es = np.zeros([len(tic_index)], dtype=np.bool)\n",
    "for row in tce_labels.iterrows():\n",
    "    tic, lbl_e = row[0], row[1]['disp_e']\n",
    "    if tic in tic_index:\n",
    "        lbl_es[tic_index[tic]] = (lbl_e > 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "num_cond_pos = int(np.sum(lbl_es))\n",
    "\n",
    "def pr_at_th(th):\n",
    "    pred_pos = np.any(pred_es >= th, axis=0)\n",
    "    true_pos = pred_pos & lbl_es\n",
    "    num_pred_pos = int(np.sum(pred_pos))\n",
    "    num_true_pos = int(np.sum(true_pos))\n",
    "    if num_pred_pos == 0:\n",
    "        return 1.0, 0.0\n",
    "    return float(num_true_pos) / float(num_pred_pos), float(num_true_pos) / float(num_cond_pos)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "AUC: 0.9879998795582506, max R: 1.0, max P: 1.0\n",
      "100% recall at: 27%, threshold: 0.0034616146088192194\n"
     ]
    },
    {
     "data": {
      "image/png": "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EZGk9hGl19Tda85h6PuIEt5HRLK+j5A0qWb2ERHeR0QW8j4iOgvEwhFk00NS+eVnZ3LcWanp0TndwFqYWaukLyu6cosUXTI3MU8++eTry1deGR1c0t3dPekf/tq1a3Xcccfp1Vdf1bZt28atW7Jkic455xyNjIyM217Jxo0b1dLSoueff1779u0bt2716tVasWKFDh48qC1bxp/btbOzU+eff74kadOmTZN2GBs2bFBHR4d27typPXv2jFu3YsUKrV69Wj09PXr66afHrWtpadHGjRslSZs3b560szn33HN11FFHaffu3dq1a9e4dccff7xOO+00FYvFSd+rmemKK66QFL2GE3fKZ5xxho499li98sor2r59+7h1xxxzjM466ywNDw9XfA0vvfRSNTU1adu2bTpw4MC4dWvWrNHy5cu1f/9+dXd3j1vX1dWl9evXS1LF7V544YUqFArasWOH9u7dO27dypUrtWrVKh0+fFibN28et66trU0XXXSRJOmZZ56Z9B/BunXrtHjxYu3atUu7d+8et+7EE0/UKaecor6+vkk1NTY26rLLok+ZbdmyZdLO/swzz9TSpUu1Z88evfDCC5L0+ve8dOlSnXnmmRoaGqr4vV5++eUyM23dulWHDh0at+7UU0/VCSecoNdee01bt24dt27x4sVat26d3L3idi+++GK1trZq+/bteu2118atO/nkk3XSSSfp4MGDeu6558ata29v1wUXXCBJeuqppyb9B7N+/Xp1dXVp165deumll8atW758udasWaOenh499dRT49Y1NzfrkksukSQ9++yzk/5zOvvss3X00Ufr5Zdf1s6dO8etW7ZsmU4//XQNDAxU/F7ZR0TS2Ee8+OKLWrp0KfuIWewjSthHRLK4jyi9iR8dHZ3071FiH1HC+4jIQt5HSJr0GrOPiPA+IrKQ9xET/x1nnYV4gh0zWyHpZ/HDv3P3X59m/M8UHeXxvLuvmcc6bpf0/vjh19z9vbU8/9Zbb32DpF2S9I53vENLly59fV1TU5Pa2to0Ojr6+n8CpTca5ct0X/PZfc3bX2gOHDig7u5urV27Vu3t7fwVt8bXkL/QLIx9RF9fn7q7u19/o84+Itt/xWUfMfsjPbZs2aLzzjtPZjZpu+wjIryPiCzUfcThw4e1adOm19+3zOQ1ZB8R4X3EmCzvI67+5H26auhH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\n",
      "text/plain": [
       "<Figure size 1200x740 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from matplotlib import pyplot as plt\n",
    "\n",
    "ps, rs, ths = ([], [], [])\n",
    "th = np.max(pred_es)\n",
    "while th >= 0.0:\n",
    "    p, r = pr_at_th(th)\n",
    "    ps.append(p)\n",
    "    rs.append(r)\n",
    "    ths.append(th)\n",
    "    th -= 0.0005\n",
    "    \n",
    "from sklearn import metrics\n",
    "\n",
    "print(f'AUC: {metrics.auc(rs, ps)}, max R: {max(rs)}, max P: {max(ps)}')\n",
    "    \n",
    "i = len(rs) - 1\n",
    "while rs[i] == 1.0:\n",
    "    i -= 1\n",
    "i += 1\n",
    "print(f'100% recall at: {int(ps[i] * 100)}%, threshold: {ths[i]}')\n",
    "\n",
    "fig, ax = plt.subplots(figsize=(6, 3.7), dpi=200)\n",
    "\n",
    "ax.spines['top'].set_color('#808080')\n",
    "ax.spines['right'].set_color('#808080')\n",
    "ax.spines['left'].set_color('#808080')\n",
    "ax.spines['bottom'].set_color('#808080')\n",
    "ax.tick_params(direction='in', color='#808080')\n",
    "\n",
    "plt.grid(color='#c0c0c0', linestyle='--', linewidth=0.5)\n",
    "\n",
    "plt.ylabel('Precision', fontweight='bold')\n",
    "plt.xlabel('Recall', fontweight='bold')\n",
    "\n",
    "plt.xlim((0.0, 1.0))\n",
    "plt.ylim((0.0, 1.0))\n",
    "\n",
    "_ = plt.plot(rs, ps)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
